package org.jeecg.modules.checdw.Job;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.checdw.entity.AgChecdw;
import org.jeecg.modules.checdw.entity.DetaCheCDWRecord;
import org.jeecg.modules.checdw.mapper.AgChecdwMapper;
import org.jeecg.modules.checdw.service.IAgChecdwService;
import org.jeecg.modules.cheldygx.entity.AgCheldygx;
import org.jeecg.modules.cheldygx.service.IAgCheldygxService;
import org.jeecg.modules.shextdj.entity.DetaShextData;
import org.jeecg.modules.tongxjl.entity.AgTongxjl;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Stream;

import static java.lang.StrictMath.*;

@Slf4j
public class syncChecdw implements Job {
    @SneakyThrows
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        log.info(String.format("同步车厂定位记录，任务执行了，时间:" + DateUtils.formatDateTime()));
        long t1 = System.currentTimeMillis();
        syncData();
        long t2 = System.currentTimeMillis();
        log.info(" 同步车厂定位记录，任务执行结束了，执行时间:" + (t2-t1));
    }

    @Autowired
    private IAgChecdwService agChecdwService;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    private IAgCheldygxService agCheldygxService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    AgChecdwMapper agChecdwMapper;
    boolean yetFinishSync = false;

    // 2个gps坐标计算出方位角
    double getAngleByGps(double lat1,double lng1,double lat2,double lng2){
        double PI = 3.1415926;
        double x = sin(lng2 - lng1) * cos(lat2);
        double y = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lng2 - lng1);
        double angle = atan2(x,y) * 180 / PI;
        return angle>0?angle:angle+360;
    }

    // 同步车场定位数据
    public Result<?> syncData() throws Exception {
        // 如果上次没同步完，直接返回
        if (yetFinishSync) {
            System.out.println("yet over");
            return null;
        }

        Map<String, Object> map = new HashMap<>();
        Map<String, Object> map2 = new HashMap<>();
        map2.put("page", 1);
        map2.put("size", 5000);
        map.put("pagination", map2);

        map2 = new HashMap<>();
        map2.put("direction", "ASC");
        List list2 = new ArrayList();

        list2.add("sj");
        map2.put("fields", list2);
        map.put("sort", map2);

        map2 = new HashMap<>();
        Map map3 = new HashMap<String, Object>() {
            {
                put("field", "sj");
                put("ops", "gt");
                long shijc = DateUtils.str2Timestamp("2020-01-01 00:00:00").getTime();

                AgChecdw agChecdw = agChecdwService.getOne(new QueryWrapper<AgChecdw>().orderByDesc("shangbsj"), false);

                if (agChecdw != null) {

                    shijc = DateUtils.getTimestamp(agChecdw.getShangbsj()).getTime();
                }
                System.out.println("最终时间戳" + shijc);
                put("value", shijc);
            }
        };

        List list = new ArrayList<>();
        list.add(map3);
        map2.put("and", map3);
        map.put("filter", map2);
        map.put("t", DateUtils.getTimestamp());

        System.out.println(JSONObject.toJSON(map).toString());

        DetaShextData detaShextData = restTemplate.postForObject("http://26.29.23.93:8080/dw/tsingoalposition", map, DetaShextData.class);
      //  System.out.println("摄像头数据"+detaShextData+"\n");


        if (detaShextData != null) {
            List<AgChecdw> batch = new ArrayList<>();
            List<AgChecdw> redis = new ArrayList <>();
            System.out.println(detaShextData.getRecords().size());

            //LinkedList<AgChecdw> chec = new LinkedList<>();


            List<AgCheldygx> agCheldygxes = agCheldygxService.list();

            if (redis.size()<agCheldygxes.size()){
                for (int i = 0; i < agCheldygxes.size(); i++) {
                    redis.add(i,new AgChecdw());
                }
                redisUtil.set("carPosList",redis);
            }


            for (String str : detaShextData.getRecords()
            ) {
                DetaCheCDWRecord detaCheCDWRecord = JSON.parseObject(str, new TypeReference<DetaCheCDWRecord>() {
                });
                if (detaShextData != null) {
                    AgChecdw agChecdw = new AgChecdw();
                    AgChecdw agChecdw2 = new AgChecdw();

                    agChecdw.setDianzbq(detaCheCDWRecord.getTagId());
                    agChecdw2.setDianzbq(detaCheCDWRecord.getTagId());

                    //车牌号
                    AgCheldygx agCheldygx = agCheldygxService.getOne(new QueryWrapper<AgCheldygx>().eq("dianzbq", agChecdw.getDianzbq()), false);
                    if (agCheldygx != null){
                        agChecdw.setCheph(agCheldygx.getId());
                        agChecdw2.setCheph(agCheldygx.getCheph());
                    }

                    if (detaCheCDWRecord.getPosY2() != null && !detaCheCDWRecord.getPosY2().equals("")){
                        agChecdw.setLatitude(detaCheCDWRecord.getPosY2());
                        agChecdw2.setLatitude(detaCheCDWRecord.getPosY2());

                    }

                    if (detaCheCDWRecord.getPosX2() != null && !detaCheCDWRecord.getPosX2().equals("")){
                        agChecdw.setLongitude(detaCheCDWRecord.getPosX2());
                        agChecdw2.setLongitude(detaCheCDWRecord.getPosX2());

                    }
                    agChecdw.setPosy(detaCheCDWRecord.getPosY());
                    agChecdw2.setPosy(detaCheCDWRecord.getPosY());
                    agChecdw.setPosx(detaCheCDWRecord.getPosX());
                    agChecdw2.setPosx(detaCheCDWRecord.getPosX());

                   // System.out.println("纬度"+detaCheCDWRecord.getPosY2()+"\n");

                    if (detaCheCDWRecord.getCapcity() != null && !detaCheCDWRecord.getCapcity().equals("")){
                        agChecdw.setBiaoqdl(detaCheCDWRecord.getCapcity());
                        agChecdw2.setBiaoqdl(detaCheCDWRecord.getCapcity());

                    }

                    long timestamp = Long.parseLong(detaCheCDWRecord.getSj());
                    Date date = DateUtils.getDate(timestamp);
                    agChecdw.setShangbsj(date);
                    agChecdw2.setShangbsj(date);

                  //  System.out.println(timestamp + "\t" + DateUtils.date2Str(date, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")));

                    agChecdw.setCreateTime(new Date());
                    agChecdw2.setCreateTime(new Date());

                    AgChecdw agChecdw1 = agChecdwService.getOne(new QueryWrapper<AgChecdw>().eq("shangbsj", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(agChecdw.getShangbsj())).eq("cheph", agChecdw.getCheph()), false);

//log.info("上报时间"+agChecdw.getShangbsj()+"数据"+agChecdw1.getShangbsj()+"2"+agChecdw2.getShangbsj());
                  if (agChecdw1==null){
                      batch.add(agChecdw);
                      //  log.info("车场"+String.valueOf(agChecdw2)+"\n"+agCheldygxes);
                      //存入redis

                      for (int i = 0; i < agCheldygxes.size(); i++) {

                          if (agChecdw2.getCheph()!=null&&agChecdw2.getCheph().contains(agCheldygxes.get(i).getCheph())){
                              log.info("redis"+agChecdw2.getCheph()+"redis2"+agCheldygxes.get(i).getCheph()+"num"+i);
                              redis.set(i,agChecdw2);
                          }

                      }
                      redisUtil.set("carPosList",redis );

                  }



                }
            }

            //遍历集合，计算方位角
            for (int i = 1; i <= detaShextData.getRecords().size()-1; i++) {

                Double d= getAngleByGps(Double.parseDouble(batch.get(i-1).getLatitude()),Double.parseDouble(batch.get(i-1).getLongitude())
                        ,Double.parseDouble(batch.get(i).getLatitude()),Double.parseDouble(batch.get(i).getLongitude()));
                String fangweij=String.valueOf(d);
                batch.get(i).setId(batch.get(i).getId());
                batch.get(i).setFangwj(fangweij);

                agChecdwService.updateById(batch.get(i));

            }
            try {
                yetFinishSync = true;
                agChecdwService.saveBatch(removeDuplicateOutputField(batch), 5000);

            } catch (Exception error) {
                System.out.println(error.getMessage());
            } finally {
                yetFinishSync = false;
            }

            return Result.ok();
        }
        return Result.error("同步数据失败");
    }





    // 查询在停车场里的车辆列表，最新上报时间并且isinpark==1
    @GetMapping(value = "/isInParklist")
    public Result<?> isInParklist() {

        Page <AgChecdw> page = new Page<AgChecdw>(1, 999);
        IPage <AgChecdw> pageList = agChecdwService.page(page, new QueryWrapper<AgChecdw>()
                .select("distinct *")
                .eq("isinpark", 1)
                .orderByDesc("shangbsj"));

        return Result.ok(pageList);
    }


    private static List<AgChecdw> removeDuplicateOutputField(List<AgChecdw> list) {
        Set<AgChecdw> set = new TreeSet<>(new Comparator<AgChecdw>() {
            @Override
            public int compare(AgChecdw o1, AgChecdw o2) {
                int compareToResult = 1;//==0表示重复
                //根据需求添加StringUtils.equals(o1.getUserName(), o2.getUserName()) ；
                if(StringUtils.equals(o1.getCheph(), o2.getCheph()) &&
                        StringUtils.equals(o1.getShangbsj().toString(), o2.getShangbsj().toString())) {
                    compareToResult = 0;
                }

                return compareToResult;
            }
        });
        set.addAll(list);
        System.out.println("去重"+set.size());
        return new ArrayList<>(set);
    }

}
